using Microsoft.VisualStudio.TestTools.UnitTesting;
using MongoDB.Bson.Serialization;
using MongoDB.Driver;

namespace MongoScienceDAL.Core.Tests
{
    /// <summary>
    /// This is a key test singleton holder that allows all tests to run of the same database connection.
    /// This is primarly to overcome multiple serialisation registration issues.
    /// </summary>
    public static class TestHarness
    {
        public static string TestConnectionString { get { return "mongodb://localhost"; } }
        public static string TestDatabaseName { get { return "UnitTestDB"; } }
        public static string ScienceTypesCollectionName { get { return "scienceTypes"; } }
        public static string ScienceCollectionsCollectionName { get { return "scienceCollections"; } }

        public static ScienceSeralisationProvider SerialisationProvider { get; set; }
        public static DataSource DataSource { get; set; }

        static TestHarness()
        {
            var client = new MongoClient(TestConnectionString);
            var server = client.GetServer();

            //Drop the dataSource
            var result = server.DropDatabase(TestDatabaseName);
            if (!result.Ok) throw new InternalTestFailureException("Unable to drop dataSource.");

            //get the database
            DataSource = new DataSource(server.GetDatabase(TestDatabaseName));

            //Register class map
            ScienceDatabaseClassMap.RegisterTypes();

            //Register Bson thing
            SerialisationProvider = new ScienceSeralisationProvider();
            BsonSerializer.RegisterSerializationProvider(SerialisationProvider);
            SerialisationProvider.Add(typeof(ScienceEntry), new ScienceEntrySerializer(DataSource));
        }

        public static void ResetDatabase()
        {
            //get a server reference
            var server = DataSource.Database.Server;

            //If it dosent exist we dont need to do anything
            if (!DataSource.Database.Server.DatabaseExists(TestDatabaseName))
                return;

            //drop db
            DataSource.Database.Server.DropDatabase(TestDatabaseName);

            //reset our reference
            DataSource = new DataSource(server.GetDatabase(TestDatabaseName));

            //reset serialisation provider
            SerialisationProvider.ClearAll();
            SerialisationProvider.Add(typeof(ScienceEntry), new ScienceEntrySerializer(DataSource));
        }
    }
}